/*
* Copyright (c) 2010-2013 Ruben Chakhmakhchyan. All rights reserved.
* 
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Eclipse Public License
* Version 1.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://opensource.org/licenses/EPL-1.0 and read it before using this file.
*/

#include "plugin_impl.h"


char* NPP_GetMIMEDescription( void )
{
    return "application/x-pixel-fi:Image Acquisition Plugin";
}

NPError NPP_Initialize( void )
{
    return NPERR_NO_ERROR;
}

void NPP_Shutdown( void )
{
}

// here the plugin creates an instance of our Plugin object which
// will be associated with this newly created plugin instance and will do all the neccessary job
NPError NPP_New( NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved )
{
    if ( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    NPError result = NPERR_NO_ERROR;

    _Plugin* plugin = new _Plugin( instance );

    if ( plugin == NULL )
        return NPERR_OUT_OF_MEMORY_ERROR;

    instance->pdata = ( void* ) plugin;

    // tell the browser plugin is windowless
    //NPN_SetValue( instance, NPPVpluginWindowBool, NULL );

    return result;
}

// here is the place to clean up and destroy the Plugin object
NPError NPP_Destroy( NPP instance, NPSavedData** save )
{
    if ( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    NPError result = NPERR_NO_ERROR;

    _Plugin* plugin = ( _Plugin* ) instance->pdata;

    if ( plugin != NULL )
    {
        delete plugin;
    }
    return result;
}

// during this call we know when the plugin window is ready or
// is about to be destroyed so we can do some gui specific initialization and shutdown
NPError NPP_SetWindow( NPP instance, NPWindow* npWindow )
{
    if ( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    if ( npWindow == NULL )
        return NPERR_GENERIC_ERROR;

    _Plugin* plugin = ( _Plugin* ) instance->pdata;

    if ( plugin == NULL )
        return NPERR_GENERIC_ERROR;

    bool isInitialized = plugin->m_isInitialized;

    // window just created
    if ( npWindow->window != NULL && !isInitialized )
    {
        if ( !plugin->init( npWindow ) )
        {
            delete plugin;
            plugin = NULL;
            return NPERR_MODULE_LOAD_FAILED_ERROR;
        }
    }

    // window goes away
    if ( npWindow->window == NULL && isInitialized )
        return NPERR_NO_ERROR;

    // window resized
    if ( npWindow->window != NULL && isInitialized )
        return NPERR_NO_ERROR;

    // this should not happen, nothing to do
    if ( npWindow->window == NULL && !isInitialized )
        return NPERR_NO_ERROR;

    return NPERR_NO_ERROR;
}

// here the plugin is asked by Mozilla to tell if it is scriptable
// we should return a valid interface id and a pointer to 
NPError	NPP_GetValue( NPP instance, NPPVariable variable, void *value )
{
    if ( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    NPError result = NPERR_NO_ERROR;

    if ( instance == NULL )
        return NPERR_GENERIC_ERROR;

    _Plugin* plugin = ( _Plugin* ) instance->pdata;

    if ( plugin == NULL )
        return NPERR_GENERIC_ERROR;

    switch ( variable )
    {
    case NPPVpluginNameString:
        *( ( char** ) value ) = "NPRuntime Pixel-fi Plugin";
        break;

    case NPPVpluginDescriptionString:
        *( ( char** ) value ) = "NPRuntime Pixel-fi Plugin for Image Acuisition";
        break;

    case NPPVpluginScriptableNPObject:
        *( NPObject** ) value = plugin->createScriptableObject();
        break;

    default:
        result = NPERR_GENERIC_ERROR;
    }

    return result;
}

NPError NPP_NewStream( NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype )
{
    if ( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    return NPERR_NO_ERROR;
}

int32_t NPP_WriteReady( NPP instance, NPStream *stream )
{
    if( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    return 0x0fffffff;
}

int32_t NPP_Write( NPP instance, NPStream *stream, int32_t offset, int32_t len, void *buffer )
{   
    if( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    return len;
}

NPError NPP_DestroyStream( NPP instance, NPStream *stream, NPError reason )
{
    if( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    return NPERR_NO_ERROR;
}

void NPP_StreamAsFile( NPP instance, NPStream* stream, const char* fname )
{
    if ( instance == NULL )
        return;
}

void NPP_Print( NPP instance, NPPrint* printInfo )
{
    if( instance == NULL )
        return;
}

void NPP_URLNotify( NPP instance, const char* url, NPReason reason, void* notifyData )
{
    if( instance == NULL )
        return;

    //_Plugin * pPlugin = ( _Plugin * )instance->pdata;
    //if ( pPlugin )
    //	pPlugin->urlNotify( url, reason, notifyData );
}

NPError NPP_SetValue( NPP instance, NPNVariable variable, void *value )
{
    if( instance == NULL )
        return NPERR_INVALID_INSTANCE_ERROR;

    return NPERR_NO_ERROR;
}

int16_t	NPP_HandleEvent( NPP instance, void* event )
{
    if( instance == NULL )
        return 0;

    int16_t result = 0;

    _Plugin* plugin = ( _Plugin* ) instance->pdata;

    if ( plugin )
        result = plugin->handleEvent( event );

    return result;
}

NPObject* NPP_GetScriptableInstance( NPP instance )
{
    if( instance == NULL )
        return NULL;

    _Plugin* plugin = ( _Plugin* ) instance->pdata;

    NPObject* result = NULL;

    if ( !plugin )
        result = plugin->createScriptableObject();

    return result;
}
